package wangwenjun.phase2.concurrencypattern.producerconsumer.lockcondition;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import util.ThreadUtil;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.IntStream;

/**
 * @author ChangLiang
 * @date 2020/6/22
 */
public class AppTest {

    @Test
    @DisplayName("multi producers and multi consumers")
    public void test() throws InterruptedException {
        final EventQueue eventQueue = new EventQueue();
        IntStream.range(0, 3).forEach(i -> new Thread(() -> {
            while (true) {
                ThreadUtil.sleepForMilliSeconds(ThreadLocalRandom.current().nextInt(200, 1000));
                eventQueue.offer(new EventQueue.Event());
            }
        }, "producer-thread-" + i).start());
        IntStream.range(0, 2).forEach(i -> new Thread(() -> {
            while (true) {
                ThreadUtil.sleepForMilliSeconds(ThreadLocalRandom.current().nextInt(200, 1000));
                eventQueue.take();
            }
        }, "consumer-thread-" + i).start());

        Thread.currentThread().join();
    }

    @Test
    @DisplayName("multi producers and multi consumers")
    public void test2() throws InterruptedException {
        final EventQueue eventQueue = new EventQueue(1);
        IntStream.range(0, 3).forEach(i -> new Thread(() -> {
            while (true) {
                ThreadUtil.sleepForMilliSeconds(ThreadLocalRandom.current().nextInt(200, 1000));
                eventQueue.offerFair(new EventQueue.Event());
            }
        }, "producer-thread-" + i).start());
        IntStream.range(0, 2).forEach(i -> new Thread(() -> {
            while (true) {
                ThreadUtil.sleepForMilliSeconds(ThreadLocalRandom.current().nextInt(200, 1000));
                eventQueue.takeFair();
            }
        }, "consumer-thread-" + i).start());

        Thread.currentThread().join();
    }

}
